﻿using System;
using System.Collections.Generic;
using INDEX = System.UInt64;

namespace Library.Collections.Specialized
{
    public sealed class ArrayEnumerator<T> : IEnumerator<T>, IDisposable
    {
        T[] arraySegment;
        INDEX offset;
        INDEX count;
        long next;
        T current;

        public ArrayEnumerator(T[] arraySegment, INDEX offset, INDEX count)
        {
            this.arraySegment = arraySegment;
            this.offset = offset;
            this.count = count;
        }

        public void Dispose()
        {
        }

        public bool MoveNext()
        {
            if (next < 0)
                return false;

            if ((INDEX)next < count)
            {
                current = arraySegment[offset + (INDEX)(next++)];
                return true;
            }

            next = -1;
            return false;
        }

        public T Current
        {
            get { return current; }
        }

        public void Reset()
        {
            next = 0;
        }

        object System.Collections.IEnumerator.Current
        {
            get
            {
                return current;
            }
        }
    }

    public sealed class ArrayEnumeratorReversed<T> : IEnumerator<T>, IDisposable
    {
        T[] array;
        long next;
        T current;
        INDEX count;
        INDEX n;

        public ArrayEnumeratorReversed(T[] array, INDEX offset, INDEX count)
        {
            this.array = array;
            this.count = count;
            this.n = offset + count - 1;
        }

        public void Dispose()
        {
        }

        public bool MoveNext()
        {
            if (next < 0)
                return false;

            if ((INDEX)next < count)
            {
                current = array[n - (INDEX)(next++)];
                return true;
            }

            next = -1;
            return false;
        }

        public T Current
        {
            get { return current; }
        }

        public void Reset()
        {
            next = 0;
        }

        object System.Collections.IEnumerator.Current
        {
            get
            {
                return current;
            }
        }
    }
}